﻿using System;
using System.Collections.Generic;
using System.Linq;
using EzDesk.Core.Model;
using EzDesk.Core.ServiceImpl.Repositories;
using EzDesk.Core.ServiceImpl.Filters;
using EzDesk.Core.Interface;
using EzDesk.Utility.Log;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreService : ICoreService
    {
        private UserRepository _userRepository;
        private DeptRepository _deptRepository;
        private AppRepository _appRepository;
        private PositionRepository _positionRepository;
        private GroupRepository _groupRepository;
        private FeedRepository _feedRepository;
        private FeedTemplateRepository _feedTemplateRepository;
        private PermissionRepository _permissionRepository;
        private OrganizationRepository _organizationRepository;

        public CoreService(
            UserRepository userRepository,
            DeptRepository deptRepository,
            AppRepository appRepository,
            PositionRepository positionRepository,
            GroupRepository groupRepository,
            FeedRepository updateFeedRepository,
            FeedTemplateRepository feedTemplateReposiory,
            PermissionRepository permissionRepository,
            OrganizationRepository organizationRepository
            )
        {
            this._appRepository = appRepository;
            this._deptRepository = deptRepository;
            this._userRepository = userRepository;
            this._positionRepository = positionRepository;
            this._groupRepository = groupRepository;
            this._feedRepository = updateFeedRepository;
            this._feedTemplateRepository = feedTemplateReposiory;
            this._permissionRepository = permissionRepository;
            this._organizationRepository = organizationRepository;

            LogEx.TRACE("CoreService - CoreService", "初始化CoreService");
        }


        #region [ private methods ]

        private ICoreService self
        {
            get
            {
                return (ICoreService)this;
            }
        }


        private Guid[] convertSingleIdToIdCollection(Guid singleId)
        {
            Guid[] guids = new Guid[1]
            {
                singleId
            };
            return guids;
        }

        private Guid[] convertIdStrsToIdCollection(string idStrs)
        {
            var idStrList = idStrs.Split(',');

            IList<Guid> idList = new List<Guid>();

            foreach (var idStr in idStrList)
            {
                Guid result;
                if (Guid.TryParse(idStr, out result))
                {
                    idList.Add(result);
                }
            }
            return idList.ToArray();
        }

        #endregion


        UserProfile ICoreService.GetUserProfileByUserName(string userName)
        {
            return _userRepository.GetAll()
                .ByUserName(userName);
        }

        UserProfile ICoreService.GetUserProfileById(Guid userId)
        {
            return _userRepository.GetById(userId);
        }

        UserProfile ICoreService.CreateEmptyUserProfile(string userName)
        {
            return _userRepository.CreateEmptyUser(userName);
        }

        void ICoreService.DeleteUserProfile(Guid userId)
        {
            _userRepository.Delete(userId);
        }

        IList<UserProfile> ICoreService.GetUserProfiles(Guid[] userIdCollection)
        {
            var allUserProfiles = _userRepository.GetAll();
            return userIdCollection.Select(id => allUserProfiles.ByUserId(id)).ToList();
        }


        IList<UserProfile> ICoreService.GetUserProfiles(string memberstring)
        {
            Guid[] userIds =
                self.GetAllUsersByMemberString(memberstring)
                .Select(p => p.Id)
                .ToArray();

            return self.GetUserProfiles(userIds);
        }

        SimpleUser ICoreService.GetSimpleUserById(Guid userId)
        {
            return  _userRepository.GetSimpleUserById(userId);
        }


        

        IList<SimpleUser> ICoreService.GetSimpleUserInfos(Guid[] userIdCollection)
        {
            var allSimpleInfo = _userRepository.GetAllSimpleUserInfo();
            return userIdCollection.Select(id => allSimpleInfo.ByUserId(id)).ToList();
        }

        IList<SimpleUser> ICoreService.GetSimpleUserInfos(string memberstring)
        {
            Guid[] userIdsToSent =
                self.GetAllUsersByMemberString(memberstring)
                .Select(p => p.Id)
                .ToArray();

            return self.GetSimpleUserInfos(userIdsToSent);
        }

        SimpleUser ICoreService.GetSimpleUserInfoByUserName(string userName)
        {
            return _userRepository.GetAllSimpleUserInfo()
                .ByUserName(userName);
        }

        IList<SimpleUser> ICoreService.GetUsersInDept(Guid deptId)
        {
            return _userRepository.GetAll()
                .InDept(deptId)
                .ToList();
        }

        IList<Dept> ICoreService.GetAllDepts()
        {
            return _deptRepository.GetAll()
                .ToList();
        }

        Dept ICoreService.GetDeptById(Guid deptId)
        {
            return _deptRepository.GetById(deptId);
        }

        Dept ICoreService.CreateDept(string deptName)
        {
            //判断名字不重复
            if (_deptRepository.GetAll().ByDeptName(deptName) != null)
            {
                throw new Exception("Duplicated Dept Name");
            }

            //创建相应分组
            var newGroup = self.CreateGroup(null, null, deptName, 1 /* GroupType = 1 部门组 */);

            // 创建新的Dept 写入
            var newDept = new Dept()
            {
                Id = new Guid(),
                DeptName = deptName,
                GroupId = newGroup.Id,
            };
            _deptRepository.Add(newDept);
            return newDept;
        }
        void ICoreService.DeleteDept(Guid deptId)
        {
            var dept = _deptRepository.GetById(deptId);
            // todo: check if dept has a groupId
            _groupRepository.Delete(dept.GroupId.GetValueOrDefault());
            _deptRepository.Delete(dept.Id);
        }
        void ICoreService.ChangeUserDept(Guid userId, Guid deptId)
        {
            Dept dept = _deptRepository.GetById(deptId);
            if (dept == null)
            {
                throw new Exception("Dept not found!!!");
            }

            // 从当前部门删除
            self.RemoveUserFromCurrentDept(userId);

            // 添加入新的部门
            var user = _userRepository.GetById(userId);
            user.DeptId = deptId;
            _userRepository.Update(user);

            // 将用户加入到对应的Group
            self.AddUserInGroup(dept.GroupId.GetValueOrDefault(), userId);

        }

        void ICoreService.ChangeUserPosition(Guid userId, Guid positionId)
        {
            // validate positionId

            var user = _userRepository.GetById(userId);
            user.PositionId = positionId;
            _userRepository.Update(user);
        }

        IList<SimpleUser> ICoreService.GetUsersInPosition(Guid posId)
        {
            return _userRepository.GetAll()
                .InPosition(posId)
                .ToList();
        }

        void ICoreService.RemoveUserFromCurrentDept(Guid userId)
        {
            var user = _userRepository.GetById(userId);

            //todo: check if user is in a dept

            var dept = _deptRepository.GetById(user.DeptId.GetValueOrDefault());

            if (user.DeptId.HasValue)
            {
                self.RemoveUserFromGroup(dept.GroupId.GetValueOrDefault(), user.Id);
                user.DeptId = null;
            }
            _userRepository.Update(user);
        }

        void ICoreService.ChangeDeptName(Guid deptId, string deptName)
        {
            var dept = _deptRepository.GetById(deptId);

            // todo: check if dept's group is null

            var group = _groupRepository.GetById(dept.GroupId.GetValueOrDefault());
            group.Description = deptName;
            _groupRepository.Update(group);

            dept.DeptName = deptName;
            _deptRepository.Update(dept);
        }


        IList<Position> ICoreService.GetPositions()
        {
            return _positionRepository.GetAll()
                .ToList();
        }

        Position ICoreService.CreatePosition(string descrition, int priority)
        {
            var position = new Position()
            {
                Id = Guid.NewGuid(),
                Description = descrition,
                Priority = priority,
            };
            _positionRepository.Add(position);
            return position;
        }

        void ICoreService.ChangePositionPriority(Guid posId, int priority)
        {
            var position = _positionRepository.GetById(posId);
            position.Priority = priority;
            _positionRepository.Update(position);
        }

        void ICoreService.ChangePositionDescription(Guid posId, string description)
        {
            var position = _positionRepository.GetById(posId);
            position.Description = description;
            _positionRepository.Update(position);
        }

        void ICoreService.DeletePosition(Guid positionId)
        {
            _positionRepository.Delete(positionId);
        }



        FeedTemplate ICoreService.CreateFeedTemplate(Guid appId, string titleTemplate, string bodyTemplate, int type)
        {
            throw new NotImplementedException();
        }

        void ICoreService.DeleteFeedTemplate(Guid id)
        {
            throw new NotImplementedException();
        }

        FeedTemplate ICoreService.GetFeedTemplateById(Guid templateId)
        {
            return _feedTemplateRepository.GetById(templateId);
        }

        IList<FeedTemplate> ICoreService.GetFeedTemplate(string templateName, Guid appId)
        {
            throw new NotImplementedException();
        }





        public void UpdateHeadIcon(Guid userId, byte[] iconData, string imageType)
        {
            _userRepository.UpdateHeadIcon(userId, iconData, imageType);
        }

        public ImageData GetHeadIcon(Guid userId)
        {
            return _userRepository.GetHeadIcon(userId);
        }




        public void UpdateUserProfile(UserProfile userProfile)
        {
            _userRepository.Update(userProfile, true);
        }
    }
}
